<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow-IPC: ipc::transport::asio_local_stream_socket Namespace Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow-IPC<span id="projectnumber">&#160;1.0.2</span>
   </div>
   <div id="projectbrief">Flow-IPC project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceipc.html">ipc</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1transport.html">transport</a></li><li class="navelem"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html">asio_local_stream_socket</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#namespaces">Namespaces</a> &#124;
<a href="#nested-classes">Classes</a> &#124;
<a href="#typedef-members">Typedefs</a> &#124;
<a href="#func-members">Functions</a>  </div>
  <div class="headertitle"><div class="title">ipc::transport::asio_local_stream_socket Namespace Reference</div></div>
</div><!--header-->
<div class="contents">

<p>Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets including transmission of native handles through such streams; and peer process credentials acquisition.  
<a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#details">More...</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="namespaces" name="namespaces"></a>
Namespaces</h2></td></tr>
<tr class="memitem:namespaceipc_1_1transport_1_1asio__local__stream__socket_1_1local__ns"><td class="memItemLeft" align="right" valign="top">namespace &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket_1_1local__ns.html">local_ns</a></td></tr>
<tr class="memdesc:namespaceipc_1_1transport_1_1asio__local__stream__socket_1_1local__ns"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for boost.asio Unix domain socket namespace. <br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classipc_1_1transport_1_1asio__local__stream__socket_1_1Opt__peer__process__credentials.html">Opt_peer_process_credentials</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Gettable (read-only) socket option for use with <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae" title="Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy).">asio_local_stream_socket::Peer_socket</a> <code>.get_option()</code> in order to get the connected opposing peer process's credentials (PID/UID/GID/etc.).  <a href="classipc_1_1transport_1_1asio__local__stream__socket_1_1Opt__peer__process__credentials.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="typedef-members" name="typedef-members"></a>
Typedefs</h2></td></tr>
<tr class="memitem:a0ad6afc0bbf995a5b84528f96315f4a2"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a0ad6afc0bbf995a5b84528f96315f4a2">Protocol</a> = local_ns::stream_protocol</td></tr>
<tr class="memdesc:a0ad6afc0bbf995a5b84528f96315f4a2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for boost.asio Unix domain stream-socket protocol.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a0ad6afc0bbf995a5b84528f96315f4a2">More...</a><br /></td></tr>
<tr class="separator:a0ad6afc0bbf995a5b84528f96315f4a2"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a154986f10d30d850de86fc3924766e66"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a154986f10d30d850de86fc3924766e66">Acceptor</a> = Protocol::acceptor</td></tr>
<tr class="memdesc:a154986f10d30d850de86fc3924766e66"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for boost.asio Unix domain stream-socket acceptor (listening guy) socket.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a154986f10d30d850de86fc3924766e66">More...</a><br /></td></tr>
<tr class="separator:a154986f10d30d850de86fc3924766e66"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1788f9dbd896bb71b3693f9ae25b40ae"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> = Protocol::socket</td></tr>
<tr class="memdesc:a1788f9dbd896bb71b3693f9ae25b40ae"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy).  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">More...</a><br /></td></tr>
<tr class="separator:a1788f9dbd896bb71b3693f9ae25b40ae"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a05656e297b98f4c370841d2f9be52a5f"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f">Endpoint</a> = Protocol::endpoint</td></tr>
<tr class="memdesc:a05656e297b98f4c370841d2f9be52a5f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for boost.asio Unix domain peer stream-socket endpoint.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f">More...</a><br /></td></tr>
<tr class="separator:a05656e297b98f4c370841d2f9be52a5f"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="func-members" name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:a1022dfd42e9a0d6eab8384b0352decb0"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0">nb_write_some_with_native_handle</a> (flow::log::Logger *logger_ptr, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *peer_socket, <a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a> payload_hndl, const <a class="el" href="namespaceipc_1_1util.html#ae0be7edba7e30ffa3f8b742af621f2ab">util::Blob_const</a> &amp;payload_blob, <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *err_code)</td></tr>
<tr class="memdesc:a1022dfd42e9a0d6eab8384b0352decb0"><td class="mdescLeft">&#160;</td><td class="mdescRight">boost.asio extension similar to <code>peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(payload_blob)</code> with the added capability of accompanying the <code>Blob_const payload_blob</code> with a native handle to be transmitted to the opposing peer.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0">More...</a><br /></td></tr>
<tr class="separator:a1022dfd42e9a0d6eab8384b0352decb0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a9ae82b2a234b218704c62fb616d6fcc5"><td class="memItemLeft" align="right" valign="top">size_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5">nb_read_some_with_native_handle</a> (flow::log::Logger *logger_ptr, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *peer_socket, <a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a> *target_payload_hndl, const <a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96">util::Blob_mutable</a> &amp;target_payload_blob, <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *err_code, int message_flags=0)</td></tr>
<tr class="memdesc:a9ae82b2a234b218704c62fb616d6fcc5"><td class="mdescLeft">&#160;</td><td class="mdescRight">boost.asio extension similar to <code>peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(target_payload_blob)</code> with the added capability of reading (from opposing peer) not only <code>Blob_mutable target_payload_blob</code> but an optionally accompanying native handle.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5">More...</a><br /></td></tr>
<tr class="separator:a9ae82b2a234b218704c62fb616d6fcc5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af0833f160dffd7f1c6921d27883a186b"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#af0833f160dffd7f1c6921d27883a186b">release_native_peer_socket</a> (<a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a> &amp;&amp;peer_socket_native_or_null)</td></tr>
<tr class="memdesc:af0833f160dffd7f1c6921d27883a186b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Little utility that returns the raw Native_handle suitable for <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae" title="Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy).">Peer_socket</a> to the OS.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#af0833f160dffd7f1c6921d27883a186b">More...</a><br /></td></tr>
<tr class="separator:af0833f160dffd7f1c6921d27883a186b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a68071e53f4a048084f8ad26ff3ac6711"><td class="memTemplParams" colspan="2">template&lt;typename Task_err &gt; </td></tr>
<tr class="memitem:a68071e53f4a048084f8ad26ff3ac6711"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711">async_write_with_native_handle</a> (flow::log::Logger *logger_ptr, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *peer_socket, <a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a> payload_hndl, const <a class="el" href="namespaceipc_1_1util.html#ae0be7edba7e30ffa3f8b742af621f2ab">util::Blob_const</a> &amp;payload_blob, Task_err &amp;&amp;on_sent_or_error)</td></tr>
<tr class="memdesc:a68071e53f4a048084f8ad26ff3ac6711"><td class="mdescLeft">&#160;</td><td class="mdescRight">boost.asio extension similar to <code>boost::asio::async_write(Peer_socket&amp;, Blob_const, Task_err_sz)</code> with the added capability of accompanying the <code>Blob_const</code> with a native handle to be transmitted to the opposing peer.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711">More...</a><br /></td></tr>
<tr class="separator:a68071e53f4a048084f8ad26ff3ac6711"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:acf7bdf0c727cbf0c5297125c762e1001"><td class="memTemplParams" colspan="2">template&lt;typename Task_err_blob , typename Target_payload_blob_func , typename Should_interrupt_func &gt; </td></tr>
<tr class="memitem:acf7bdf0c727cbf0c5297125c762e1001"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001">async_read_with_target_func</a> (flow::log::Logger *logger_ptr, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *peer_socket, Target_payload_blob_func &amp;&amp;target_payload_blob_func, Should_interrupt_func &amp;&amp;should_interrupt_func, Task_err_blob &amp;&amp;on_rcvd_or_error)</td></tr>
<tr class="memdesc:acf7bdf0c727cbf0c5297125c762e1001"><td class="mdescLeft">&#160;</td><td class="mdescRight">boost.asio extension similar to <code>boost::asio::async_read(Peer_socket&amp;, Blob_mutable, Task_err_sz)</code> with the difference that the target buffer (<a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96" title="Short-hand for an mutable blob somewhere in memory, stored as exactly a void* and a size_t.">util::Blob_mutable</a>) is determined by calling the arg-supplied function at the time when at least 1 byte is available to read, instead of the buffer being given direcly as an arg.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001">More...</a><br /></td></tr>
<tr class="separator:acf7bdf0c727cbf0c5297125c762e1001"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ae811e863245b8226af4c40d373ed9a73"><td class="memTemplParams" colspan="2">template&lt;typename Task_err , typename Should_interrupt_func &gt; </td></tr>
<tr class="memitem:ae811e863245b8226af4c40d373ed9a73"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#ae811e863245b8226af4c40d373ed9a73">async_read_interruptible</a> (flow::log::Logger *logger_ptr, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *peer_socket, <a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96">util::Blob_mutable</a> target_payload_blob, Should_interrupt_func &amp;&amp;should_interrupt_func, Task_err &amp;&amp;on_rcvd_or_error)</td></tr>
<tr class="memdesc:ae811e863245b8226af4c40d373ed9a73"><td class="mdescLeft">&#160;</td><td class="mdescRight">boost.asio extension similar to <code>boost::asio::async_read(Peer_socket&amp;, Blob_mutable, Task_err_sz)</code> with the difference that it can be canceled/interrupted via <code>should_interrupt_func()</code> in the same way as the otherwise more complex <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#ae811e863245b8226af4c40d373ed9a73">More...</a><br /></td></tr>
<tr class="separator:ae811e863245b8226af4c40d373ed9a73"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af872520154fc00afaa59c7eec607a225"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f">Endpoint</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#af872520154fc00afaa59c7eec607a225">endpoint_at_shared_name</a> (flow::log::Logger *logger_ptr, const <a class="el" href="namespaceipc_1_1transport.html#a33de1c256addb3964b839dc2dd407d24">Shared_name</a> &amp;absolute_name, <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *err_code=0)</td></tr>
<tr class="memdesc:af872520154fc00afaa59c7eec607a225"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns an <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f" title="Short-hand for boost.asio Unix domain peer stream-socket endpoint.">Endpoint</a> corresponding to the given absolute Shared_name, so that an <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a154986f10d30d850de86fc3924766e66" title="Short-hand for boost.asio Unix domain stream-socket acceptor (listening guy) socket.">Acceptor</a> or <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae" title="Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy).">Peer_socket</a> could be bound to it.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#af872520154fc00afaa59c7eec607a225">More...</a><br /></td></tr>
<tr class="separator:af872520154fc00afaa59c7eec607a225"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a677a303f9f81cc5661bd2b34a29309f7"><td class="memTemplParams" colspan="2">template&lt;typename Task_err &gt; </td></tr>
<tr class="memitem:a677a303f9f81cc5661bd2b34a29309f7"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a677a303f9f81cc5661bd2b34a29309f7">on_wait_writable_or_error</a> (flow::log::Logger *logger_ptr, const <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> &amp;sys_err_code, <a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a> payload_hndl, const <a class="el" href="namespaceipc_1_1util.html#ae0be7edba7e30ffa3f8b742af621f2ab">util::Blob_const</a> &amp;payload_blob, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *peer_socket, Task_err &amp;&amp;on_sent_or_error)</td></tr>
<tr class="memdesc:a677a303f9f81cc5661bd2b34a29309f7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Helper of <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a> used as the callback executed when waiting for writability of the given connected local peer socket, with the idea to execute a native <code>sendmsg()</code> call and all further parts of the async send op started by <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a677a303f9f81cc5661bd2b34a29309f7">More...</a><br /></td></tr>
<tr class="separator:a677a303f9f81cc5661bd2b34a29309f7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a21a4f47fcb36b51c30f45e27d79ca8d8"><td class="memTemplParams" colspan="2">template&lt;bool TARGET_TBD, typename Task_err_blob , typename Target_payload_blob_func , typename Should_interrupt_func &gt; </td></tr>
<tr class="memitem:a21a4f47fcb36b51c30f45e27d79ca8d8"><td class="memTemplItemLeft" align="right" valign="top">void&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a21a4f47fcb36b51c30f45e27d79ca8d8">on_wait_readable_or_error</a> (flow::log::Logger *logger_ptr, const <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> &amp;sys_err_code, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *peer_socket, Should_interrupt_func &amp;&amp;should_interrupt_func, Task_err_blob &amp;&amp;on_rcvd_or_error, Target_payload_blob_func &amp;&amp;target_payload_blob_func, <a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96">util::Blob_mutable</a> target_payload_blob, size_t n_rcvd_so_far)</td></tr>
<tr class="memdesc:a21a4f47fcb36b51c30f45e27d79ca8d8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Helper of <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a> containing its core (asynchronously) recursive implementation.  <a href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a21a4f47fcb36b51c30f45e27d79ca8d8">More...</a><br /></td></tr>
<tr class="separator:a21a4f47fcb36b51c30f45e27d79ca8d8"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets including transmission of native handles through such streams; and peer process credentials acquisition. </p>
<h3>Rationale</h3>
<p >These exist, in the first place, because internally such things as <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a> needed them for impl purposes. However they are of general usefulness publicly and hence are not tucked away under <code>detail/</code>. Because, from a public API point of view, they are orthogonal to the main public APIs (like <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a>), they are in a segregated namespace.</p>
<p >That said, to conserve time without sacrificing reusability, generally speaking features were implemented only when there was an active use case for each &ndash; or the cost of adding them was low. Essentially APIs are written in such a way as to be generally usable in the same spirit as built-in boost.asio APIs &ndash; or at least reasonably natural to get to that point in the future.</p>
<h3>Overview</h3>
<p >As of this writing <code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html" title="Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets includi...">asio_local_stream_socket</a></code> has the following features w/r/t local stream (Unix domain) sockets:</p><ul>
<li>Convenience aliases (<code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket_1_1local__ns.html" title="Short-hand for boost.asio Unix domain socket namespace.">local_ns</a></code>, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae" title="Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy).">Peer_socket</a>, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a154986f10d30d850de86fc3924766e66" title="Short-hand for boost.asio Unix domain stream-socket acceptor (listening guy) socket.">Acceptor</a>, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f" title="Short-hand for boost.asio Unix domain peer stream-socket endpoint.">Endpoint</a>, etc.).</li>
<li>Socket option for use with boost.asio API <code>Peer_socket::get_option()</code> that gets the opposing process's credentials (PID, UID, ...) (<a class="el" href="classipc_1_1transport_1_1asio__local__stream__socket_1_1Opt__peer__process__credentials.html" title="Gettable (read-only) socket option for use with asio_local_stream_socket::Peer_socket ....">Opt_peer_process_credentials</a>).</li>
<li>Writing of blob + native handle combos (boost.asio supports only the former) (<a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a>, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>, etc.).</li>
<li>Reading of blob + native handle combos (boost.asio supports only the former) (<a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a>).</li>
<li>More advanced composed blob reading operations (<a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>, at least).</li>
</ul>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000001">Todo:</a></b></dt><dd>At least <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">asio_local_stream_socket::async_read_with_target_func()</a> can be extended to other stream sockets (TCP, etc.). In that case it should be moved to a different namespace however (perhaps named <code>asio_stream_socket</code>; could then move the existing <code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html" title="Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets includi...">asio_local_stream_socket</a></code> inside that one and rename it <code>local</code>).</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000002">Todo:</a></b></dt><dd><code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html" title="Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets includi...">asio_local_stream_socket</a></code> additional feature: APIs that can read and write native sockets together with accompanying binary blobs can be extended to handle an arbitrary number of native handles (per call) as opposed to only 0 or 1. The main difficulty here is designing a convenient and stylish, yet performant, API.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000003">Todo:</a></b></dt><dd><code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html" title="Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets includi...">asio_local_stream_socket</a></code> additional feature: APIs that can read and write native handles together with accompanying binary blobs can be extended to handle scatter/gather semantics for the aforementioned blobs, matching standard boost.asio API functionality.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000004">Todo:</a></b></dt><dd><code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html" title="Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets includi...">asio_local_stream_socket</a></code> additional feature: Non-blocking APIs like <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a> and <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a> can gain blocking counterparts, matching standard boost.asio API functionality.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000005">Todo:</a></b></dt><dd><code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html" title="Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets includi...">asio_local_stream_socket</a></code> additional feature: <code>async_read_some_with_native_handle()</code> &ndash; async version of existing <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a>. Or another way to put it is, equivalent of boost.asio <code>Peer_socket::async_read_some()</code> but able to read native handle(s) with the blob. Note: This API would potentially be usable inside the impl of existing APIs (code reuse).</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000006">Todo:</a></b></dt><dd><code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html" title="Additional (versus boost.asio) APIs for advanced work with local stream (Unix domain) sockets includi...">asio_local_stream_socket</a></code> additional feature: <code>async_read_with_native_handle()</code> &ndash; async version of existing <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a>, plus the "stubborn" behavior of built-in <code>async_read()</code> free function. Or another way to put it is, equivalent of boost.asio <code>async_read&lt;Peer_socket&gt;()</code> but able to read native handle(s) with the blob. Note: This API would potentially be usable inside the impl of existing APIs (code reuse).</dd></dl>
<h3>Implementation notes</h3>
<p >As one would expect the native-handle-transmission APIs use Linux <code>recvmsg()</code> and <code>sendmsg()</code> with the <code>SCM_RIGHTS</code> ancillary-message type. For some of the to-dos mentioned above:</p><ul>
<li>Both of those functions take buffers in terms of <code>iovec</code> arrays; the present impl merely provides a 1-array. It would be pretty easy to extend this to do scatter/gather.</li>
<li>To offer blocking versions, one can simply start a <code>flow::async::Single_thread_task_loop</code> each time and <code>post()</code> onto it in <code>S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</code> mode. Alternatively one could write more performant versions that would directly use the provided sockets in blocking mode; this would be much more work. </li>
</ul>
</div><h2 class="groupheader">Typedef Documentation</h2>
<a id="a154986f10d30d850de86fc3924766e66" name="a154986f10d30d850de86fc3924766e66"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a154986f10d30d850de86fc3924766e66">&#9670;&nbsp;</a></span>Acceptor</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a154986f10d30d850de86fc3924766e66">ipc::transport::asio_local_stream_socket::Acceptor</a> = typedef Protocol::acceptor</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for boost.asio Unix domain stream-socket acceptor (listening guy) socket. </p>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html#l00111">111</a> of file <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html">asio_local_stream_socket_fwd.hpp</a>.</p>

</div>
</div>
<a id="a05656e297b98f4c370841d2f9be52a5f" name="a05656e297b98f4c370841d2f9be52a5f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a05656e297b98f4c370841d2f9be52a5f">&#9670;&nbsp;</a></span>Endpoint</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f">ipc::transport::asio_local_stream_socket::Endpoint</a> = typedef Protocol::endpoint</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for boost.asio Unix domain peer stream-socket endpoint. </p>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html#l00117">117</a> of file <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html">asio_local_stream_socket_fwd.hpp</a>.</p>

</div>
</div>
<a id="a1788f9dbd896bb71b3693f9ae25b40ae" name="a1788f9dbd896bb71b3693f9ae25b40ae"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1788f9dbd896bb71b3693f9ae25b40ae">&#9670;&nbsp;</a></span>Peer_socket</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">ipc::transport::asio_local_stream_socket::Peer_socket</a> = typedef Protocol::socket</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy). </p>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html#l00114">114</a> of file <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html">asio_local_stream_socket_fwd.hpp</a>.</p>

</div>
</div>
<a id="a0ad6afc0bbf995a5b84528f96315f4a2" name="a0ad6afc0bbf995a5b84528f96315f4a2"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0ad6afc0bbf995a5b84528f96315f4a2">&#9670;&nbsp;</a></span>Protocol</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a0ad6afc0bbf995a5b84528f96315f4a2">ipc::transport::asio_local_stream_socket::Protocol</a> = typedef local_ns::stream_protocol</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for boost.asio Unix domain stream-socket protocol. </p>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html#l00108">108</a> of file <a class="el" href="asio__local__stream__socket__fwd_8hpp_source.html">asio_local_stream_socket_fwd.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Function Documentation</h2>
<a id="ae811e863245b8226af4c40d373ed9a73" name="ae811e863245b8226af4c40d373ed9a73"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ae811e863245b8226af4c40d373ed9a73">&#9670;&nbsp;</a></span>async_read_interruptible()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Task_err , typename Should_interrupt_func &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void ipc::transport::asio_local_stream_socket::async_read_interruptible </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *&#160;</td>
          <td class="paramname"><em>peer_socket</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96">util::Blob_mutable</a>&#160;</td>
          <td class="paramname"><em>target_payload_blob</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Should_interrupt_func &amp;&amp;&#160;</td>
          <td class="paramname"><em>should_interrupt_func</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Task_err &amp;&amp;&#160;</td>
          <td class="paramname"><em>on_rcvd_or_error</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>boost.asio extension similar to <code>boost::asio::async_read(Peer_socket&amp;, Blob_mutable, Task_err_sz)</code> with the difference that it can be canceled/interrupted via <code>should_interrupt_func()</code> in the same way as the otherwise more complex <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </p>
<p >So think of it as either:</p><ul>
<li><code>async_read()</code> with added <code>should_interrupt_func()</code> feature; or</li>
<li><code><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a></code> minus <code>target_payload_blob_func()</code> feature. Or formally, it's as-if that one was used but with a <code>target_payload_blob_func()</code> that simply returns <code>target_payload_blob</code>.</li>
</ul>
<p >Omitting detailed comments already present in <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a> doc header; just skip the parts to do with <code>target_payload_blob_func()</code>.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Task_err</td><td>See <code>on_rcvd_or_error</code> arg. </td></tr>
    <tr><td class="paramname">Should_interrupt_func</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
    <tr><td class="paramname">peer_socket</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
    <tr><td class="paramname">on_rcvd_or_error</td><td>The completion handler; it is passed either the success code (all requested bytes were read), or an error code (pipe is hosed). </td></tr>
    <tr><td class="paramname">target_payload_blob</td><td><code><a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96" title="Short-hand for an mutable blob somewhere in memory, stored as exactly a void* and a size_t.">util::Blob_mutable</a></code> object describing the memory area into which we shall write on successful receipt of data. </td></tr>
    <tr><td class="paramname">should_interrupt_func</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket_8hpp_source.html#l00268">268</a> of file <a class="el" href="asio__local__stream__socket_8hpp_source.html">asio_local_stream_socket.hpp</a>.</p>

</div>
</div>
<a id="acf7bdf0c727cbf0c5297125c762e1001" name="acf7bdf0c727cbf0c5297125c762e1001"></a>
<h2 class="memtitle"><span class="permalink"><a href="#acf7bdf0c727cbf0c5297125c762e1001">&#9670;&nbsp;</a></span>async_read_with_target_func()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Task_err_blob , typename Target_payload_blob_func , typename Should_interrupt_func &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void ipc::transport::asio_local_stream_socket::async_read_with_target_func </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *&#160;</td>
          <td class="paramname"><em>peer_socket</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Target_payload_blob_func &amp;&amp;&#160;</td>
          <td class="paramname"><em>target_payload_blob_func</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Should_interrupt_func &amp;&amp;&#160;</td>
          <td class="paramname"><em>should_interrupt_func</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Task_err_blob &amp;&amp;&#160;</td>
          <td class="paramname"><em>on_rcvd_or_error</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>boost.asio extension similar to <code>boost::asio::async_read(Peer_socket&amp;, Blob_mutable, Task_err_sz)</code> with the difference that the target buffer (<a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96" title="Short-hand for an mutable blob somewhere in memory, stored as exactly a void* and a size_t.">util::Blob_mutable</a>) is determined by calling the arg-supplied function at the time when at least 1 byte is available to read, instead of the buffer being given direcly as an arg. </p>
<p >By determining where to target when there are actual data available, one can avoid unnecessary copying in the meantime; among other applications.</p>
<h3>Behavior</h3>
<p >boost.asio's <code>async_read()</code> free function is generically capable of receiving into a sequence of 1+ buffers on a connected stream socket, continuing until either the entire sequence is fully filled to the byte; or an error (not counting would-block, which just means keep trying to make progress when possible). We act exactly the same with the following essential differences being the exceptions:</p><ul>
<li>The target buffer is determined once system indicates at least 1 byte of data is available to actually read off socket; it's not supplied as an arg.<ul>
<li>To determine it, we call <code>target_payload_blob_func()</code> which must return the <a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96" title="Short-hand for an mutable blob somewhere in memory, stored as exactly a void* and a size_t.">util::Blob_mutable</a>.</li>
</ul>
</li>
<li>One can cancel the (rest of the) operation via <code>should_interrupt_func()</code>. This is called just after being internally informed the socket is ready for reading, so just before the 1st <code>target_payload_blob_func()</code> call, and ahead of each subsequent burst of non-blockingly-available bytes as well. If it returns <code>true</code>, then the operation is canceled; the target buffer (if it has even been determined) is not written to further; and <code>on_rcvd_or_error()</code> is never invoked. Note that <code>should_interrupt_func()</code> may be called ages after whatever outside interrupt-causing condition has occurred; typically your impl would merely check for that condition being the case (e.g., "have we encountered idle timeout earlier?").</li>
<li>Once the handler is called, its signature is similar (<code>Error_code</code>, <code>size_t</code> of bytes received) but with one added arg, <code>const Blob_mutable&amp; target_payload_blob</code>, which is simply a copy of the light-weight object returned per preceding bullet point.<ul>
<li>It is possible <code>target_payload_blob_func()</code> is never called; in this case the error code shall be truthy, and the reported size received shall be 0. In this case disregard the <code>target_payload_blob</code> value received; it shall be a null/empty blob.</li>
<li>The returned <a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96" title="Short-hand for an mutable blob somewhere in memory, stored as exactly a void* and a size_t.">util::Blob_mutable</a> may have <code>.size() == 0</code>. In this case we shall perform no actual read; and will simply invoke the handler immediately upon detecting this; the reported error code shall be falsy, and the reported size received shall be 0.</li>
</ul>
</li>
<li>If <code>peer_socket-&gt;non_blocking() == false</code> at entry to this function, it shall be <code>true</code> at entry to the handler, except it <em>might</em> be false if the handler receives a truthy <code>Error_code</code>. (Informally: In that case, the connection should be considered hosed in any case and must not be used for traffic.)</li>
<li>More logging, as a convenience.</li>
</ul>
<p >It is otherwise identical... but certain aspects of <code>async_read()</code> are not included in the present function, however, though merely because they were not necessary as of this writing and hence excluded for simplicity; these are formally described below.</p>
<h3>Thread safety</h3>
<p >Like <code>async_read()</code>, the (synchronous) call is not thread-safe with respect to the given <code>*peer_socket</code> against all/most calls operating on the same object. Moreover, this extends to the brief time period when the first byte is available. Since there is no way of knowing when that might be, essentially you should consider this entire async op as not safe for concurrent execution with any/most calls operating on the same <code>Peer_socket</code>, in the time period [entry to <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>, entry to <code>target_payload_blob_func()</code>].</p>
<p >Informally, as with <code>async_read()</code>, it is unwise to do anything with <code>*peer_socket</code> upon calling the present function through when the handler begins executing.</p>
<p ><code>on_rcvd_or_error()</code> is invoked fully respecting any possible executor (typically none, else a <code>Strand</code>) associated (via <code>bind_executor()</code> usually) with it.</p>
<p >However <code>should_interrupt_func()</code> and <code>target_payload_blob()</code> are invoked directly via <code>peer_socket-&gt;get_executor()</code>, and any potential associated executor on these functions themselves is ignored. (This is the case simply because there was no internal-to-rest-of-Flow-IPC use case for acting otherwise; but it's conceivable to implement it later, albeit at the cost of some more processor cycles used.)</p>
<h3>Features of <code>boost::asio::async_read()</code> not provided here</h3>
<p >We have (consciously) made these concessions: ...see <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a> doc header. All of the listed omitted features have common-sense counterparts in the case of the present function. In addition:</p><ul>
<li><code>peer_socket</code> has to be a socket of that specific type, a local stream socket. <code>async_write()</code> is templated on the socket type and will work with other connected stream sockets, notably TCP.</li>
</ul>
<h3>Rationale</h3>
<ul>
<li>This function exists because... [text omitted &ndash; same reasoning as similar rationale for <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>].<ul>
<li>Namely, though, the main thing is being able to delay targeting the data until that data are actually available to avoid internal copying in <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a> internals.</li>
<li>The <code>should_interrupt_func()</code> feature was necessary because <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a> internals has a condition where it is obligated to stop writing to the user buffer and return to them an overall in-pipe error:<ul>
<li>idle timeout (no in-traffic for N time).</li>
<li>But the whole point of <code>async_read()</code> and therefore the present extension is to keep reading until all N bytes are here, or an error. The aforementioned condition is, in a sense, the latter: an error; except it originates locally. So <code>should_interrupt_func()</code> is a way to signal this.</li>
</ul>
</li>
</ul>
</li>
<li>As noted, this sets non-blocking mode on <code>*peer_socket</code> if needed. It does not "undo" this. Why not? After all a clean op would act as if it has nothing to do with this. Originally I (ygoldfel) did "undo" it. Then I decided otherwise for 2 reasons. 1, the situation where the "undo" itself fails made it ambiguous how to report this through the handler if everything had worked until then (unlikely as that is). 2, in coming up with a decent semantic approach for this annoying corner case that'll never really happen, and then thinking of how to document it, I realized the following practical truths: <code>Peer_socket::non_blocking()</code> mode affects only the non-<code>async*()</code> ops on <code>Peer_socket</code>, and it's common to want those to be non-blocking in the first place, if one also feels the need to use <code>async*()</code> (like the present function). So why jump through hoops for purity's sake? Of course this can be changed later.</li>
</ul>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Task_err_blob</td><td>See <code>on_rcvd_or_error</code> arg. </td></tr>
    <tr><td class="paramname">Target_payload_blob_func</td><td>See <code>target_payload_blob_func</code> arg. </td></tr>
    <tr><td class="paramname">Should_interrupt_func</td><td>See <code>should_interrupt_func</code> arg. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">peer_socket</td><td>Pointer to stream socket. If it is not connected, or otherwise unsuitable, behavior is identical to attempting <code>async_read()</code> on such a socket. If null behavior is undefined (assertion may trip). </td></tr>
    <tr><td class="paramname">on_rcvd_or_error</td><td>Handler to execute at most once on completion of the async op. It is executed as if via <code>post(peer_socket-&gt;get_executor())</code>, fully respecting any executor bound to it (via <code>bind_executor()</code>, such as a strand). It shall be passed, in this order, <code>Error_code</code> and a value equal to the one returned by <code>target_payload_blob_func()</code> earlier. The semantics of the first value is identical to that for <code>boost::asio::async_read()</code>. </td></tr>
    <tr><td class="paramname">target_payload_blob_func</td><td>Function to execute at most once, when it is first indicated by the system that data might be available on the connection. It is executed as if via <code>post(peer_socket-&gt;get_executor())</code>, but any executor bound to it (via <code>bind_executor()</code> is ignored). It takes no args and shall return <code><a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96" title="Short-hand for an mutable blob somewhere in memory, stored as exactly a void* and a size_t.">util::Blob_mutable</a></code> object describing the memory area into which we shall write on successful receipt of data. It will not be invoked at all, among other reasons, if <code>should_interrupt_func()</code> returns <code>true</code> the first time <em>it</em> is invoked. </td></tr>
    <tr><td class="paramname">should_interrupt_func</td><td>Function to execute ahead of nb-reading arriving data (copying it from kernel buffer to the target buffer); hence the general loop is await-readable/call-this-function/nb-read/repeat (until the buffer is filled, there is an error, or <code>should_interrupt_func()</code> returns <code>true</code>). It is executed as if via <code>post(peer_socket-&gt;get_executor())</code>, but any executor bound to it (via <code>bind_executor()</code> is ignored). It takes no args and shall return <code>bool</code> specifying whether to proceed with the operation (<code>false</code>) or to interrupt the whole thing (<code>true</code>). If it returns <code>true</code> then <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a> will <em>not</em> call <code>on_rcvd_or_error()</code>. Instead the user should consider <code>should_interrupt_func()</code> itself as the completion handler being invoked. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket_8hpp_source.html#l00234">234</a> of file <a class="el" href="asio__local__stream__socket_8hpp_source.html">asio_local_stream_socket.hpp</a>.</p>

</div>
</div>
<a id="a68071e53f4a048084f8ad26ff3ac6711" name="a68071e53f4a048084f8ad26ff3ac6711"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a68071e53f4a048084f8ad26ff3ac6711">&#9670;&nbsp;</a></span>async_write_with_native_handle()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Task_err &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void ipc::transport::asio_local_stream_socket::async_write_with_native_handle </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *&#160;</td>
          <td class="paramname"><em>peer_socket</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a>&#160;</td>
          <td class="paramname"><em>payload_hndl</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceipc_1_1util.html#ae0be7edba7e30ffa3f8b742af621f2ab">util::Blob_const</a> &amp;&#160;</td>
          <td class="paramname"><em>payload_blob</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Task_err &amp;&amp;&#160;</td>
          <td class="paramname"><em>on_sent_or_error</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>boost.asio extension similar to <code>boost::asio::async_write(Peer_socket&amp;, Blob_const, Task_err_sz)</code> with the added capability of accompanying the <code>Blob_const</code> with a native handle to be transmitted to the opposing peer. </p>
<dl class="section see"><dt>See also</dt><dd>Please read the "Blob/handle semantics" about working with native handle handle accompaniment, in the <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a> doc header.</dd></dl>
<p>boost.asio's <code>async_write()</code> free function is generically capable of sending a sequence of 1+ buffers on a connected stream socket, continuing until either the entire sequence is fully sent; or an error (not counting would-block, which just means keep trying to make progress when possible). The capability we add is the native handle in <code>payload_hndl</code> is also transmitted. Certain aspects of <code>async_write()</code> are not included in the present function, however, though merely because they were not necessary as of this writing and hence excluded for simplicity; these are formally described below.</p>
<h3>Formal behavior</h3>
<p >This function requires that <code>payload_blob</code> be non-empty; and <code>payload_hndl.null() == false</code>. (If you want to send a non-empty buffer but no handle, then just use boost.asio <code>async_write()</code>. As of this writing the relevant OS shall not support sending a handle but a null buffer.)</p>
<p >The function exits without blocking. The sending occurs asynchronously. A successful operation is defined as sending all of the blob; and the native handle. <code>on_sent_or_error()</code> shall be called at most once, indicating the outcome of the operation. (Informally: Most of the time, though asynchronous, this should be a very fast op. This deals with local (Unix domain as of this writing) peer connections; and the other side likely uses <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">ipc::transport::Native_socket_stream</a> which takes care to read incoming messages ASAP at all times; therefore blocking when sending should be rarer than even with remote TCP traffic.) The following are all the possible outcomes:</p><ul>
<li><code>on_sent_or_error(Error_code())</code> is executed as if <code>post()</code>ed on <code>peer_socket-&gt;get_executor()</code> (the <code>flow::util::Task_engine</code>, a/k/a boost.asio <code>io_context</code>, associated with <code>*peer_socket</code>), where <code>N == payload_blob.size()</code>. This indicates the entire buffer, and the handle, were sent successfully.</li>
<li><code>on_sent_or_error(E)</code>, where <code>bool(E) == true</code>, is executed similarly. This indicates the send did not fully succeed, and <code>E</code> specifies why this happened. No indication is given how many bytes were successfully sent (if any even were). (Informally, there's likely not much difference between those 2 outcomes. Either way, the connection is hosed.)<ul>
<li><code>E == boost::asio::error::operation_aborted</code> is possible and indicates your own code canceled pending async work such as by destroying <code>*peer_socket</code>. Informally, the best way to deal with it is know it's normal when stuff is shutting down; and to do nothing other than maybe logging, but even then to not assume all relevant objects even exist; really it's best to just return right away. Know that upon that return the handler's captured state will be freed, as in all cases.</li>
<li><code>E</code> will never indicate would-block.</li>
</ul>
</li>
<li><code>on_sent_or_error()</code> is canceled and not called at all, such as possibly when <code>stop()</code>ing the underlying <code>Task_engine</code>. This is similar to the aforementioned <code>operation_aborted</code> situation. Know that upon that return the handler's captured state <em>will</em> be freed at the time of whatever shutdown/cancellation step.</li>
</ul>
<p >Items are extensively logged on <code>*logger_ptr</code>, and we follow the normal best practices to avoid verbose messages at the severities strictly higher than <code>TRACE</code>. In particular, any error is logged as a <code>WARNING</code>, so in particular there's no need to for caller to specifically log about the details of a non-false <code>Error_code</code>.</p>
<p >Thread safety is identical to that of <code>async_write_some()</code>.</p>
<h3>Features of <code>boost::asio::async_write()</code> not provided here</h3>
<p >We have (consciously) made these concessions:</p><ul>
<li><code>payload_blob</code> is a single blob. <code>async_write()</code> is templated in such a way as to accept that or a <em>sequence</em> of <code>Blob_const</code>s, meaning it supports scatter/gather.</li>
<li>There are also fancier advanced-async-flow-control overloads of <code>async_write()</code> with more features we haven't replicated. However the simplest overload only has the preceding 3 bullet points on us.</li>
</ul>
<h3>Rationale</h3>
<p >This function exists because elsewhere in <a class="el" href="namespaceipc_1_1transport.html" title="Flow-IPC module providing transmission of structured messages and/or low-level blobs (and more) betwe...">ipc::transport</a> needed it internally. It is a public API basically opportunistically: it's generic enough to be useful in its own right potentially, but as of this writing there's no use case. This explains the aforementioned concessions compared to boost.asio <code>async_write()</code> free function. All, without exception, can be implemented without controversy. It would be busy-work and was omitted simply because there was no need. If we wanted to make an "official-looking" boost.asio extension then there would be merit in no longer conceding those concessions.</p>
<p >Update: <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">transport::Native_socket_stream</a>'s impl has been split into itself on top and <a class="el" href="classipc_1_1transport_1_1sync__io_1_1Native__socket__stream.html" title="Implements both sync_io::Native_handle_sender and sync_io::Native_handle_receiver concepts by using a...">transport::sync_io::Native_socket_stream</a> as its core &ndash; also available for public use. Because the latter is now the part doing the low-level I/O, by <code><a class="el" href="namespaceipc_1_1transport_1_1sync__io.html" title="sync_io-pattern counterparts to async-I/O-pattern object types in parent namespace ipc::transport.">sync_io</a></code> pattern's nature it can no longer be doing boost.asio async-waits but rather outsources them to the user of that object (<a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">transport::Native_socket_stream</a> being a prime example). So that means the present function is no longer used by Flow-IPC internally as of this writing. Still it remains a perfectly decent API; so leaving it available.</p>
<p >There are to-dos elsewhere to perhaps generalize this guy and his bro(s) to support both boost.asio and <code><a class="el" href="namespaceipc_1_1transport_1_1sync__io.html" title="sync_io-pattern counterparts to async-I/O-pattern object types in parent namespace ipc::transport.">sync_io</a></code>. It would be some ungodly API, but it could have a boost.asio-target wrapper unchanged from the current signature.</p>
<p >These 3 paragraphs apply, to one extent or another, to <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>, <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>, and <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#ae811e863245b8226af4c40d373ed9a73" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_interruptible()</a>. </p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Task_err</td><td>boost.asio handler with same signature as <code>flow::async::Task_asio_err</code>. It can be bound to an executor (commonly, a <code>strand</code>); this will be respected. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">peer_socket</td><td>Pointer to stream socket. If it is not connected, or otherwise unsuitable, behavior is identical to attempting <code>async_write()</code> on such a socket. If null behavior is undefined (assertion may trip). </td></tr>
    <tr><td class="paramname">payload_hndl</td><td>The native handle to transmit. If <code>payload_hndl.is_null()</code> behavior is undefined (possible assertion trip). </td></tr>
    <tr><td class="paramname">payload_blob</td><td>The buffer to transmit. Reiterating the above outcome semantics: Either there is no error, and then the <code>N</code> passed to the handler callback will equal <code>payload_blob.size()</code>; or there is a truthy <code>Error_code</code>, and <code>N</code> will be strictly less than <code>payload_blob.size()</code>. </td></tr>
    <tr><td class="paramname">on_sent_or_error</td><td>Handler to execute at most once on completion of the async op. It is executed as if via <code>post(peer_socket-&gt;get_executor())</code>, fully respecting any executor bound to it (via <code>bind_executor()</code>, such as a strand). It shall be passed <code>Error_code</code>. The semantics of these values are shown above. Informally: falsy <code>Error_code</code> indicates total success of sending both items; truthy <code>Error_code</code> indicates a connection-fatal error prevented us from some or both being fully sent; one should disregard <code>operation_aborted</code> and do nothing; else one should consider the connection as hosed (possibly gracefully) and take steps having discovered this. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket_8hpp_source.html#l00171">171</a> of file <a class="el" href="asio__local__stream__socket_8hpp_source.html">asio_local_stream_socket.hpp</a>.</p>

<p class="reference">References <a class="el" href="ipc__core_2src_2ipc_2util_2util_8cpp_source.html#l00158">ipc::util::blob_data()</a>, <a class="el" href="native__handle_8cpp_source.html#l00061">ipc::util::Native_handle::null()</a>, and <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html#l00031">on_wait_writable_or_error()</a>.</p>

<p class="reference">Referenced by <a class="el" href="native__socket__stream__impl__snd_8cpp_source.html#l00846">ipc::transport::sync_io::Native_socket_stream::Impl::snd_async_write_q_head_payload()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a68071e53f4a048084f8ad26ff3ac6711_cgraph.svg" width="615" height="172"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a68071e53f4a048084f8ad26ff3ac6711_icgraph.svg" width="384" height="71"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="af872520154fc00afaa59c7eec607a225" name="af872520154fc00afaa59c7eec607a225"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af872520154fc00afaa59c7eec607a225">&#9670;&nbsp;</a></span>endpoint_at_shared_name()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f">Endpoint</a> ipc::transport::asio_local_stream_socket::endpoint_at_shared_name </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceipc_1_1transport.html#a33de1c256addb3964b839dc2dd407d24">Shared_name</a> &amp;&#160;</td>
          <td class="paramname"><em>absolute_name</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns an <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a05656e297b98f4c370841d2f9be52a5f" title="Short-hand for boost.asio Unix domain peer stream-socket endpoint.">Endpoint</a> corresponding to the given absolute Shared_name, so that an <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a154986f10d30d850de86fc3924766e66" title="Short-hand for boost.asio Unix domain stream-socket acceptor (listening guy) socket.">Acceptor</a> or <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae" title="Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy).">Peer_socket</a> could be bound to it. </p>
<p >TRACE logging possible; WARNING on error.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">absolute_name</td><td>Name. </td></tr>
    <tr><td class="paramname">err_code</td><td>See <code>flow::Error_code</code> docs for error reporting semantics. <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> generated: <code>boost::asio::error::invalid_argument</code> (endpoint failed to initialize specifically because the given or computed address/name ended up too long to fit into natively-mandated data structures; or because there are invalid characters therein, most likely forward-slash). </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>If it did not throw (which cannot happen if <code>err_code</code> non-null): default-cted <code>Endpoint</code> on error (if and only if <code>*err_code</code> truthy); the actual <code>Endpoint</code> otherwise (on success). </dd></dl>

<p class="definition">Definition at line <a class="el" href="detail_2asio__local__stream__socket_8cpp_source.html#l00028">28</a> of file <a class="el" href="detail_2asio__local__stream__socket_8cpp_source.html">asio_local_stream_socket.cpp</a>.</p>

<p class="reference">References <a class="el" href="detail_2asio__local__stream__socket_8cpp_source.html#l00028">endpoint_at_shared_name()</a>, <a class="el" href="shared__name_8cpp_source.html#l00150">ipc::util::Shared_name::size()</a>, and <a class="el" href="shared__name_8cpp_source.html#l00140">ipc::util::Shared_name::str()</a>.</p>

<p class="reference">Referenced by <a class="el" href="sync__io_2detail_2native__socket__stream__impl_8cpp_source.html#l00281">ipc::transport::sync_io::Native_socket_stream::Impl::async_connect()</a>, <a class="el" href="detail_2asio__local__stream__socket_8cpp_source.html#l00028">endpoint_at_shared_name()</a>, and <a class="el" href="native__socket__stream__acceptor_8cpp_source.html#l00037">ipc::transport::Native_socket_stream_acceptor::Native_socket_stream_acceptor()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_af872520154fc00afaa59c7eec607a225_cgraph.svg" width="402" height="98"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_af872520154fc00afaa59c7eec607a225_icgraph.svg" width="436" height="131"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a9ae82b2a234b218704c62fb616d6fcc5" name="a9ae82b2a234b218704c62fb616d6fcc5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a9ae82b2a234b218704c62fb616d6fcc5">&#9670;&nbsp;</a></span>nb_read_some_with_native_handle()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">size_t ipc::transport::asio_local_stream_socket::nb_read_some_with_native_handle </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *&#160;</td>
          <td class="paramname"><em>peer_socket</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a> *&#160;</td>
          <td class="paramname"><em>target_payload_hndl</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96">util::Blob_mutable</a> &amp;&#160;</td>
          <td class="paramname"><em>target_payload_blob</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">int&#160;</td>
          <td class="paramname"><em>message_flags</em> = <code>0</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>boost.asio extension similar to <code>peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(target_payload_blob)</code> with the added capability of reading (from opposing peer) not only <code>Blob_mutable target_payload_blob</code> but an optionally accompanying native handle. </p>
<p >In other words it attempts to immediately read at least 1 byte into <code>*target_payload_blob</code> and, if also present, the native handle into <code>*target_payload_hndl</code>; returns would-block error code if this would require blocking; or another error if the connection has become hosed. Performing <code>peer_socket-&gt;read_some()</code> given <code>peer_socket-&gt;non_blocking() == true</code> has the same semantics except it cannot and will not read any native handle. (It would probably just "eat it"/ignore it; though we have not tested that at this time.)</p>
<p >Certain aspects of <code>Peer_socket::read_some()</code> are not included in the present function, however, though merely because they were not necessary as of this writing and hence excluded for simplicity; these are formally described below.</p>
<h3>Formal behavior</h3>
<p >This function requires that <code>target_payload_blob</code> be non-empty. It shall at entry set <code>*target_payload_hndl</code> so that <code>target_payload_hndl-&gt;null() == true</code>. <code>target_payload_hndl</code> (the pointer) must not be null. (If you want to receive into non-empty buffer but expect no handle, then just use boost.asio <code>Peer_socket::read_some()</code>. If you want to receive a non-empty buffer but no handle, then just use boost.asio <code>async_write()</code>. As of this writing the relevant OS shall not support receiving a handle but a null buffer.)</p>
<p >The function exits without blocking. The receiving occurs synchronously, if possible, or does not occur otherwise. A successful operation is defined as receiving 1+ bytes into the blob; and the native handle if it was present. It is not possible that a native handle is received but 0 bytes of the blob are. See <code>flow::Error_code</code> docs for error reporting semantics (if <code>err_code</code> is non-null, <code>*err_code</code> is set to code or success; else exception with that code is thrown in the former [non-success] case).</p>
<p >The following are all the possible outcomes:</p><ul>
<li><code>N &gt; 0</code> is returned; and <code>*err_code == <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code()</a></code> if non-null. This indicates 1 or more (<code>N</code>) bytes were placed at the start of the buffer, and <em>if</em> exactly 1 native handle handle was transmitted along with some subset of those <code>N</code> bytes, <em>then</em> it was successfully received into <code>*target_payload_hndl</code>; or else the fact there were exactly 0 such handles was successfully determined and reflected via <code>target_payload_hndl-&gt;null() == true</code>. If <code>N != target_payload_blob.size()</code>, then no further bytes can currently be read without blocking and should be tried later if desired. (Informally: In that case consider <code>Peer_socket::async_wait()</code> followed by retrying the present function, in that case.)</li>
<li>If non-null <code>err_code</code>, then <code>N == 0</code> is returned; and <code>*err_code == E</code> is set to the triggering problem. If null, then <code>flow::error::Runtime_error</code> is thrown containing <code>Error_code E</code>.<ul>
<li><code>E == boost::asio::error::would_block</code> specifically indicates the non-fatal condition wherein <code>*peer_socket</code> cannot currently receive, until it reaches readable state again (i.e., bytes and possibly handle arrive from peer).</li>
<li>Other <code>E</code> values indicate the connection is (potentially gracefully) permanently incapable of transmission.<ul>
<li>In particular <code>E == boost::asio::error::eof</code> indicates the connection was gracefully closed by peer. (Informally, this is usually not to be treated differently from other fatal errors like <code>boost::asio::error::connection_reset</code>.)</li>
<li>It may be tempting to distinguish between "true" system errors (probably from <code>boost::asio::error::</code>) and "protocol" errors from <code><a class="el" href="namespaceipc_1_1transport_1_1error.html#adfef15ef4e76cc55d652fbd9c2797297" title="All possible errors returned (via Error_code arguments) by ipc::transport functions/methods outside o...">ipc::transport::error::Code</a></code> (as of this writing <code>S_LOW_LVL_UNEXPECTED_STREAM_PAYLOAD_BEYOND_HNDL</code>): one <em>can</em> technically keep reading in the latter case, in that the underlying connection is still connected potentially. However, formally, behavior is undefined if one reads more subsequently. Informally: if the other side has violated protocol expectations &ndash; or if your side has violated expectations on proper reading (see below section on that) &ndash; then neither side can be trusted to recover logical consistency and must abandon the connection.</li>
</ul>
</li>
<li><code>E == operation_aborted</code> is not possible.</li>
</ul>
</li>
</ul>
<p >Items are extensively logged on <code>*logger_ptr</code>, and we follow the normal best practices to avoid verbose messages at the severities strictly higher than <code>TRACE</code>. In particular, any error is logged as a <code>WARNING</code>, so in particular there's no need for caller to specifically log about the details of a non-false <code>E</code>. (If this is still too slow, you may use the <code>flow::log::Config::this_thread_verbosity_override_auto()</code> to temporarily, in that thread only, disable logging. This is quite easy and performant.)</p>
<h3>Blob/handle semantics</h3>
<p >Non-blocking stream-blob-send/receive semantics must be familiar to you, such as from TCP and otherwise. By adding native handles (further, just <em>handles</em>) as accompaniment to this system, non-trivial &ndash; arguably subtle &ndash; questions are raised about how it all works together. The central question is, perhaps, if I ask to send N bytes and handle S, non-blockingly, what are the various possibilities for sending less than N bytes of the blob and whether S is also sent? Conversely, how will receiving on the other side work? The following describes those semantics and <em>mandates</em> how to properly handle it. Not following these formally leads to undefined behavior. (Informally, for the tested OS versions, it is possible to count on certain additional behaviors; but trying to do so is (1) prone to spurious changes and breakage in different OS versions and types, since much of this is undocumented; and (2) will probably just make your life <em>more</em> difficult anyway, not less. Honestly I (ygoldfel) designed it for ease of following as opposed to exactly maximal freedom of capability. So... just follow these.)</p>
<p >Firstly, as already stated, it is not possible to try sending a handle sans a blob; and it is not possible to receive a handle sans a blob. (The converse is a regular non-blocking blob write or receive op.)</p>
<p >Secondly, one must think of the handle as associated with <em>exactly the first byte</em> of the blob arg to the write call (<a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a>). Similarly, one must think of the handle as associated with <em>exactly the first byte</em> of the blob arg to the read call (<a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a>). Moreover, known OS make certain not-well-documented assumptions about message lengths. What does this all mean in practice?</p><ul>
<li>You may design your protocol however you want, except the following requirement: Define a <em>handle-containing message</em> as a combination of a blob of 1+ bytes of some known (on both sides, at the time of both sending and receipt) length N <em>and</em> exactly <em>one</em> handle. You must aim to send this message and receive it exactly as sent, meaning with message boundaries respected. (To be clear, you're free to use any technique to make N known on both sides; e.g., it may be a constant; or it may be passed in a previous message. However, it's not compatible with using a sentinel alone, as then N is unknown.)<ul>
<li>You must only transmit handles as part of handle-containing messages. Anything else is undefined behavior.</li>
</ul>
</li>
<li>Let M be a given handle-containing message with blob B of size N; and handle H. Let a <em>write op</em> be <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a> (or an <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a> based on it).<ul>
<li>You shall attempt one write op for the blob B of size N together with handle H. Do <em>not</em> intermix it with any other bytes or handles.<ul>
<li>In the non-blocking write op case (<a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a>) it may yield successfully sending N' bytes, where 1 &lt;= N' &lt; N. This means the handle was successfully sent also, because the handle is associated with the <em>first byte</em> of the write &ndash; and read &ndash; op. If this happens, don't worry about it; continue with the rest of the protocol, including sending at least the remaining (N - N') bytes of M.</li>
</ul>
</li>
<li>On the receiver side, you must symmetrically execute the read op (<a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a>, perhaps after a <code>Peer_socket::async_wait()</code>) to attempt receipt of all of M, including supplying a target blob of exactly N bytes &ndash; without mixing with any other bytes or handles. The "hard" part of this is mainly to avoid having the previous read op "cut into" M.<ul>
<li>(Informally, a common-sense way to do it just make your protocol message-based, such that the length of the next message is always known on either side.)</li>
<li>Again, if the <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a> call returns N', where 1 &lt;= N' &lt; N, then no worries. The handle S <em>will</em> have been successfully received, being associated with byte 1 of M. Keep reading the rest of M (namely, the remaining (N - N') bytes of the blob B) with more read op(s).</li>
<li>(To put a fine point on it: In known Linux versions as of this writing, if you do try to read-op N' bytes having executed write-op with N'' bytes, where N'' &gt; N', then you may observe very strange, undefined (albeit non-crashy), behavior such as S disappearing or replacing a following-message handle S'. Don't.)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p >That is admittedly many words, but really in practice it's fairly natural and simple to design a message-based protocol and implementation around it. Just do follow these; I merely wanted to be complete.</p>
<h3>Features of <code>Peer_socket::read_some()</code> not provided here</h3>
<p >We have (consciously) made these concessions: ...see <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a> doc header. All of the listed omitted features have common-sense counterparts in the case of the present function.</p>
<h3>Advanced feature on top of <code>Peer_socket::read_some()</code></h3>
<p >Lastly, <code>Peer_socket::receive()</code> is identical to <code>Peer_socket::read_some()</code> but adds an overload wherein one can pass in a (largely unportable, I (ygoldfel) think) <code>message_flags</code> bit mask. We <em>do</em> provide a close cousin of this feature via the (optional as of this writing) arg <code>native_recvmsg_flags</code>. (Rationale: We specifically omitted it in <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a>; yet add it here because the value <code>MSG_CMSG_CLOEXEC</code> has specific utility.) One may override the default (<code>0</code>) by supplying any value one would supply as the <code>int flags</code> arg of Linux's <code>recvmsg()</code> (see <code>man recvmsg</code>). As one can see in the <code>man</code> page, this is a bit mask or ORed values. Formally, however, the only value supported (does not lead to undefined behavior) is <code>MSG_CMSG_CLOEXEC</code> (please read its docs elsewhere, but in summary it sets the close-on-<code>exec</code> bit of any non-null received <code>*target_payload_blob</code>). Informally: that flag may be important for one's application; so we provide for it; however beyond that one please refer to the reasoning regarding not supporting <code>message_flags</code> in <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1022dfd42e9a0d6eab8384b0352decb0" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(pay...">nb_write_some_with_native_handle()</a> as explained in its doc header.</p>
<h3>Rationale</h3>
<p >This function exists because... [text omitted &ndash; same reasoning as similar rationale for <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>].</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">peer_socket</td><td>Pointer to stream socket. If it is not connected, or otherwise unsuitable, behavior is identical to attempting <code>read_some()</code> on such a socket. If null behavior is undefined (assertion may trip). </td></tr>
    <tr><td class="paramname">target_payload_hndl</td><td>The native handle wrapper into which to copy the received handle; it shall be set such that <code>target_payload_hndl-&gt;null() == true</code> if the read-op returned 1+ (succeeded), but those bytes were not accompanied by any native handle. It shall also be thus set if 0 is returned (indicating error including would-block and fatal errors). </td></tr>
    <tr><td class="paramname">target_payload_blob</td><td>The buffer into which to write received blob data, namely up to <code>target_payload_blob-&gt;size()</code> bytes. If null, or the size is not positive, behiavor is undefined (assertion may trip). Reiterating the above outcome semantics: Either there is no error, and then the <code>N</code> returned will be 1+; or a truthy <code>Error_code</code> is returned either via the out-arg or via thrown <code>Runtime_error</code>, and in the former case 0 is returned. </td></tr>
    <tr><td class="paramname">err_code</td><td>See <code>flow::Error_code</code> docs for error reporting semantics. <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> generated: <code>boost::asio::error::would_block</code> (socket not writable, likely because other side isn't reading ASAP), <a class="el" href="namespaceipc_1_1transport_1_1error.html#adfef15ef4e76cc55d652fbd9c2797297a8c068cf7b73b09b5ed3fa3532de1747c" title="Unable to receive incoming traffic: message contains more than: 1 blob plus 0-1 native handles.">ipc::transport::error::Code::S_LOW_LVL_UNEXPECTED_STREAM_PAYLOAD_BEYOND_HNDL</a> (strictly more than 1 handle detected in the read-op, but we support only 1 at this time; see above; maybe they didn't use above write-op function(s) and/or didn't follow anti-straddling suggestion above), other system codes (see notes above in the outcome discussion). </td></tr>
    <tr><td class="paramname">message_flags</td><td>See boost.asio <code>Peer_socket::receive()</code> overload with this arg. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>0 if non-null <code>err_code</code> and truthy resulting <code>*err_code</code>, and hence no bytes or the handle was sent; 1+ if that number of bytes were sent plus the native handle (and hence falsy <code>*err_code</code> if non-null).</dd></dl>
<h3>Implementation notes</h3>
<p >Where does the content of "Blob/handle semantics" originate? Answer: Good question, as reading <code>man</code> pages to do with <code>sendmsg()/recvmsg()/cmsg/unix</code>, etc., gives hints but really is incomplete and certainly not formally complete. Without such a description, one can guess at how <code>SOL_SOCKET/SCM_RIGHTS</code> (sending of FDs along with blobs) might work but not conclusively. I (ygoldfel) nevertheless actually correctly developed the relevant conclusions via common sense/experience... and <em>later</em> confirmed them by reading kernel source and the delightfully helpful write-up at [ <a href="https://gist.github.com/kentonv/bc7592af98c68ba2738f4436920868dc">https://gist.github.com/kentonv/bc7592af98c68ba2738f4436920868dc</a> ] (Googled "SCM_RIGHTS gist"). Reading these may give the code inspector/maintainer (you?) more peace of mind. Basically, though, the key gist is:</p><ul>
<li>The handle(s) are associated with byte 1 of the blob given to the <code>sendmsg()</code> call containing those handle(s). For this reason, to avoid protocol chaos, you should send each given handle with the same "synchronized" byte on both sides.</li>
<li>The length of that blob similarly matters &ndash; which is not normal, as otherwise message boundaries are <em>not</em> normally maintained for stream connections &ndash; and for this reason the read op must accept a result into a blob of at <em>least</em> the same same size as the corresponding write op. (For simplicity and other reasons my instructions say it should just be equal.)</li>
</ul>
<p >Lastly, I note that potentially using <code>SOCK_SEQPACKET</code> (which purports to conserve message boundaries at all times) instead of <code>SOCK_STREAM</code> (which we use) might remove all ambiguity. On the other hand it's barely documented itself. The rationale for the decision to use <code>SOCK_STREAM</code> is discussed elsewhere; this note is to reassure that I (ygoldfel) don't quite find the above complexity reason enough to switch to <code>SOCK_SEQPACKET</code>. </p>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00202">202</a> of file <a class="el" href="asio__local__stream__socket_8cpp_source.html">asio_local_stream_socket.cpp</a>.</p>

<p class="reference">References <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00202">nb_read_some_with_native_handle()</a>, and <a class="el" href="namespaceipc_1_1transport_1_1error.html#adfef15ef4e76cc55d652fbd9c2797297a8c068cf7b73b09b5ed3fa3532de1747c">ipc::transport::error::S_LOW_LVL_UNEXPECTED_STREAM_PAYLOAD_BEYOND_HNDL</a>.</p>

<p class="reference">Referenced by <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00202">nb_read_some_with_native_handle()</a>, and <a class="el" href="native__socket__stream__impl__rcv_8cpp_source.html#l00683">ipc::transport::sync_io::Native_socket_stream::Impl::rcv_nb_read_low_lvl_payload()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a9ae82b2a234b218704c62fb616d6fcc5_cgraph.svg" width="187" height="95"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a9ae82b2a234b218704c62fb616d6fcc5_icgraph.svg" width="399" height="95"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a1022dfd42e9a0d6eab8384b0352decb0" name="a1022dfd42e9a0d6eab8384b0352decb0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1022dfd42e9a0d6eab8384b0352decb0">&#9670;&nbsp;</a></span>nb_write_some_with_native_handle()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">size_t ipc::transport::asio_local_stream_socket::nb_write_some_with_native_handle </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *&#160;</td>
          <td class="paramname"><em>peer_socket</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a>&#160;</td>
          <td class="paramname"><em>payload_hndl</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceipc_1_1util.html#ae0be7edba7e30ffa3f8b742af621f2ab">util::Blob_const</a> &amp;&#160;</td>
          <td class="paramname"><em>payload_blob</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> *&#160;</td>
          <td class="paramname"><em>err_code</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>boost.asio extension similar to <code>peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;write_some(payload_blob)</code> with the added capability of accompanying the <code>Blob_const payload_blob</code> with a native handle to be transmitted to the opposing peer. </p>
<p >In other words it attempts to immediately send <code>payload_hndl</code> and at least 1 byte of <code>payload_blob</code>; returns would-block error code if this would require blocking; or another error if the connection has become hosed. Performing <code>peer_socket-&gt;write_some()</code> given <code>peer_socket-&gt;non_blocking() == true</code> has the same semantics except it cannot and will not transmit any native handle.</p>
<dl class="section see"><dt>See also</dt><dd>Please read the "Blob/handle semantics" about working with native handle accompaniment, in the <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a9ae82b2a234b218704c62fb616d6fcc5" title="boost.asio extension similar to peer_socket-&gt;non_blocking(true); auto n = peer_socket-&gt;read_some(targ...">nb_read_some_with_native_handle()</a> doc header.</dd></dl>
<p>Certain aspects of <code>Peer_socket::write_some()</code> are not included in the present function, however, though merely because they were not necessary as of this writing and hence excluded for simplicity; these are formally described below.</p>
<h3>Formal behavior</h3>
<p >This function requires that <code>payload_blob</code> be non-empty; and <code>payload_hndl.null() == false</code>. (If you want to send a non-empty buffer but no handle, then just use boost.asio <code>Peer_socket::write_some()</code>. As of this writing the relevant OS shall not support receive a handle but a null buffer.)</p>
<p >The function exits without blocking. The sending occurs synchronously, if possible, or does not occur otherwise. A successful operation is defined as sending 1+ bytes of the blob; and the native handle. It is not possible that the native handle is transmitted but 0 bytes of the blob are. See <code>flow::Error_code</code> docs for error reporting semantics (if <code>err_code</code> is non-null, <code>*err_code</code> is set to code or success; else exception with that code is thrown in the former [non-success] case). (Informally: Most of the time, assuming no error condition on the connection, the function will return success. This deals with local (Unix domain as of this writing) peer connections; and the other side likely uses <a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">ipc::transport::Native_socket_stream</a> which takes care to read incoming messages ASAP at all times; therefore would-block when sending should be rarer than even with remote TCP traffic.)</p>
<p >The following are all the possible outcomes:</p><ul>
<li><code>N &gt; 0</code> is returned; and <code>*err_code == <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code()</a></code> if non-null. This indicates 1 or more (<code>N</code>) bytes of the buffer, and the handle, were sent successfully. If <code>N != payload_blob.size()</code>, then the remaining bytes cannot currently be sent without blocking and should be tried later. (Informally: Consider <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a> in that case.)</li>
<li>If non-null <code>err_code</code>, then <code>N == 0</code> is returned; and <code>*err_code == E</code> is set to the triggering problem. If null, then <code>flow::error::Runtime_error</code> is thrown containing <code>Error_code E</code>.<ul>
<li><code>E == boost::asio::error::would_block</code> specifically indicates the non-fatal condition wherein <code>*peer_socket</code> cannot currently send, until it reaches writable state again.</li>
<li>Other <code>E</code> values indicate the connection is (potentially gracefully) permanently incapable of transmission.</li>
<li><code>E == operation_aborted</code> is not possible.</li>
</ul>
</li>
</ul>
<p >Items are extensively logged on <code>*logger_ptr</code>, and we follow the normal best practices to avoid verbose messages at the severities strictly higher than <code>TRACE</code>. In particular, any error is logged as a <code>WARNING</code>, so in particular there's no need to for caller to specifically log about the details of a non-false <code>E</code>.</p>
<h3>Features of <code>Peer_socket::write_some()</code> not provided here</h3>
<p >We have (consciously) made these concessions:</p><ul>
<li><code>payload_blob</code> is a single blob. <code>write_some()</code> is templated in such a way as to accept that or a <em>sequence</em> of <code>Blob_const</code>s, meaning it supports scatter/gather.</li>
<li>This function never blocks, regardless of <code>peer_socket-&gt;non_blocking()</code>. <code>write_some()</code> &ndash; if unable to immediately send 1+ bytes &ndash; will block until it can, if <code>peer_socket-&gt;non_blocking() == false</code> mode had been set. (That's why we named it <code>nb_...()</code>.)</li>
</ul>
<p >The following is not a concession, and these words may be redundant, but: <code>Peer_socket::write_some()</code> has 2 overloads; one that throws exception on error; and one that takes an <code>Error_code&amp;</code>; whereas we combine the two via the <code>Error_code*</code> null-vs-not dichotomy. (It's redundant, because it's just following the Flow pattern.)</p>
<p >Lastly, <code>Peer_socket::send()</code> is identical to <code>Peer_socket::write_some()</code> but adds an overload wherein one can pass in a (largely unportable, I (ygoldfel) think) <code>message_flags</code> bit mask. We do not provide this feature: again because it is not needed, but also because depending on the flag it may lead to unexpected corner cases, and we'd rather not deal with those unless needed in practice.</p>
<h3>Rationale</h3>
<p >This function exists because... [text omitted &ndash; same reasoning as similar rationale for <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>].</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">peer_socket</td><td>Pointer to stream socket. If it is not connected, or otherwise unsuitable, behavior is identical to attempting <code>write_some()</code> on such a socket. If null behavior is undefined (assertion may trip). </td></tr>
    <tr><td class="paramname">payload_hndl</td><td>The native handle to transmit. If <code>payload_hndl.is_null()</code> behavior is undefined (possible assertion trip). Reiterating the above outcome semantics: if the return value <code>N</code> indicates even 1 byte was sent, then this was successfully sent also. </td></tr>
    <tr><td class="paramname">payload_blob</td><td>The buffer to transmit. Reiterating the above outcome semantics: Either there is no error, and then the <code>N</code> returned will be 1+; or a truthy <code>Error_code</code> is returned either via the out-arg or via thrown <code>Runtime_error</code>, and in the former case 0 is returned. </td></tr>
    <tr><td class="paramname">err_code</td><td>See <code>flow::Error_code</code> docs for error reporting semantics. <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89" title="Short-hand for flow::Error_code which is very common.">Error_code</a> generated: <code>boost::asio::error::would_block</code> (socket not writable, likely because other side isn't reading ASAP), other system codes (see notes above in the outcome discussion). </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>0 if non-null <code>err_code</code> and truthy resulting <code>*err_code</code>, and hence no bytes or the handle was sent; 1+ if that number of bytes were sent plus the native handle (and hence falsy <code>*err_code</code> if non-null). </dd></dl>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00036">36</a> of file <a class="el" href="asio__local__stream__socket_8cpp_source.html">asio_local_stream_socket.cpp</a>.</p>

<p class="reference">References <a class="el" href="native__handle_8hpp_source.html#l00085">ipc::util::Native_handle::m_native_handle</a>, and <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00036">nb_write_some_with_native_handle()</a>.</p>

<p class="reference">Referenced by <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00036">nb_write_some_with_native_handle()</a>, <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html#l00031">on_wait_writable_or_error()</a>, and <a class="el" href="native__socket__stream__impl__snd_8cpp_source.html#l00740">ipc::transport::sync_io::Native_socket_stream::Impl::snd_nb_write_low_lvl_payload()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a1022dfd42e9a0d6eab8384b0352decb0_cgraph.svg" width="190" height="95"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a1022dfd42e9a0d6eab8384b0352decb0_icgraph.svg" width="827" height="168"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a21a4f47fcb36b51c30f45e27d79ca8d8" name="a21a4f47fcb36b51c30f45e27d79ca8d8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a21a4f47fcb36b51c30f45e27d79ca8d8">&#9670;&nbsp;</a></span>on_wait_readable_or_error()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;bool TARGET_TBD, typename Task_err_blob , typename Target_payload_blob_func , typename Should_interrupt_func &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void ipc::transport::asio_local_stream_socket::on_wait_readable_or_error </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> &amp;&#160;</td>
          <td class="paramname"><em>sys_err_code</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *&#160;</td>
          <td class="paramname"><em>peer_socket</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Should_interrupt_func &amp;&amp;&#160;</td>
          <td class="paramname"><em>should_interrupt_func</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Task_err_blob &amp;&amp;&#160;</td>
          <td class="paramname"><em>on_rcvd_or_error</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Target_payload_blob_func &amp;&amp;&#160;</td>
          <td class="paramname"><em>target_payload_blob_func</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1util.html#a6cb62ae434900f3a8915b33ec5d61a96">util::Blob_mutable</a>&#160;</td>
          <td class="paramname"><em>target_payload_blob</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>n_rcvd_so_far</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Helper of <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a> containing its core (asynchronously) recursive implementation. </p>
<p >Call with template param <code>TARGET_TBD == true</code> to start the wait/async-read chain; then it asynchronously triggers the <code>TARGET_TBD == false</code> form which then repats that as many times as needed to complete the target buffer.</p>
<p >It is also used directly in <code>TARGET_TBD == false</code> mode by <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#ae811e863245b8226af4c40d373ed9a73" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_interruptible()</a> which is a simpler version of <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a> that knows the target buffer from the start.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">TARGET_TBD</td><td>Must be <code>true</code> when <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a> async-invokes it, <code>false</code> when it async-invokes itself, or if <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#ae811e863245b8226af4c40d373ed9a73" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_interruptible()</a> invokes it. </td></tr>
    <tr><td class="paramname">Task_err_blob</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
    <tr><td class="paramname">Target_payload_blob_func</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. However, it can be anything (suggest <code>int</code>), if <code>TARGET_TBD == false</code> and is ignored in that case. </td></tr>
    <tr><td class="paramname">Should_interrupt_func</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
    <tr><td class="paramname">sys_err_code</td><td>The error code yielded by the <code>Peer_socket::async_wait()</code> async call for which we are the handler arg. This can be success or error but not a would-block error. </td></tr>
    <tr><td class="paramname">peer_socket</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
    <tr><td class="paramname">should_interrupt_func</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
    <tr><td class="paramname">on_rcvd_or_error</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. </td></tr>
    <tr><td class="paramname">target_payload_blob_func</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#acf7bdf0c727cbf0c5297125c762e1001" title="boost.asio extension similar to boost::asio::async_read(Peer_socket&amp;, Blob_mutable,...">async_read_with_target_func()</a>. However, it can be anything (suggest <code>0</code>), if <code>TARGET_TBD == false</code> and is ignored in that case. </td></tr>
    <tr><td class="paramname">target_payload_blob</td><td>Ignored if <code>TARGET_TBD == true</code>; otherwise it must be the result of <code>target_payload_blob_func()</code> during the <code>TARGET_TBD == false</code> invocation in this operation. </td></tr>
    <tr><td class="paramname">n_rcvd_so_far</td><td>Must be 0 if <code>TARGET_TBD == true</code>; else it must equal the number of leading bytes of <code>target_payload_blob</code> that have already been filled out by reading from socket. (Note this may be 0 even so, though it's unlikely.) </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html#l00214">214</a> of file <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html">asio_local_stream_socket.hpp</a>.</p>

</div>
</div>
<a id="a677a303f9f81cc5661bd2b34a29309f7" name="a677a303f9f81cc5661bd2b34a29309f7"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a677a303f9f81cc5661bd2b34a29309f7">&#9670;&nbsp;</a></span>on_wait_writable_or_error()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Task_err &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">void ipc::transport::asio_local_stream_socket::on_wait_writable_or_error </td>
          <td>(</td>
          <td class="paramtype">flow::log::Logger *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceipc.html#aa3192e586cc45d3e7c22463bf2760f89">Error_code</a> &amp;&#160;</td>
          <td class="paramname"><em>sys_err_code</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a>&#160;</td>
          <td class="paramname"><em>payload_hndl</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="namespaceipc_1_1util.html#ae0be7edba7e30ffa3f8b742af621f2ab">util::Blob_const</a> &amp;&#160;</td>
          <td class="paramname"><em>payload_blob</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae">Peer_socket</a> *&#160;</td>
          <td class="paramname"><em>peer_socket</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Task_err &amp;&amp;&#160;</td>
          <td class="paramname"><em>on_sent_or_error</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Helper of <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a> used as the callback executed when waiting for writability of the given connected local peer socket, with the idea to execute a native <code>sendmsg()</code> call and all further parts of the async send op started by <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>. </p>
<p >This is used as the callback either by <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a> or by itself upon <code>sendmsg()</code> encountering would-block, in which case it must wait again and invoke itself asynchronously (and so on).</p>
<p >It is <em>not</em> used once at least 1 byte (and therefore also the native handle) have been successfuly sent.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Task_err</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>. </td></tr>
    <tr><td class="paramname">sys_err_code</td><td>The error code yielded by the <code>Peer_socket::async_wait()</code> async call for which we are the handler arg. This can be success or error but not a would-block error. </td></tr>
    <tr><td class="paramname">peer_socket</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>. </td></tr>
    <tr><td class="paramname">payload_hndl</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>. </td></tr>
    <tr><td class="paramname">payload_blob</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>. </td></tr>
    <tr><td class="paramname">on_sent_or_error</td><td>See <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a68071e53f4a048084f8ad26ff3ac6711" title="boost.asio extension similar to boost::asio::async_write(Peer_socket&amp;, Blob_const,...">async_write_with_native_handle()</a>. Note that we, too, will likely blow it away via move semantics. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html#l00031">31</a> of file <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html">asio_local_stream_socket.hpp</a>.</p>

<p class="reference">References <a class="el" href="ipc__core_2src_2ipc_2util_2util_8cpp_source.html#l00158">ipc::util::blob_data()</a>, <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00036">nb_write_some_with_native_handle()</a>, and <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html#l00031">on_wait_writable_or_error()</a>.</p>

<p class="reference">Referenced by <a class="el" href="asio__local__stream__socket_8hpp_source.html#l00171">async_write_with_native_handle()</a>, and <a class="el" href="detail_2asio__local__stream__socket_8hpp_source.html#l00031">on_wait_writable_or_error()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a677a303f9f81cc5661bd2b34a29309f7_cgraph.svg" width="406" height="144"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_a677a303f9f81cc5661bd2b34a29309f7_icgraph.svg" width="600" height="90"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="af0833f160dffd7f1c6921d27883a186b" name="af0833f160dffd7f1c6921d27883a186b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af0833f160dffd7f1c6921d27883a186b">&#9670;&nbsp;</a></span>release_native_peer_socket()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void ipc::transport::asio_local_stream_socket::release_native_peer_socket </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceipc_1_1transport.html#a7ee4551983d9df16ec16a3139bac50e8">Native_handle</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>peer_socket_native_or_null</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Little utility that returns the raw Native_handle suitable for <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#a1788f9dbd896bb71b3693f9ae25b40ae" title="Short-hand for boost.asio Unix domain peer stream-socket (usually-connected-or-empty guy).">Peer_socket</a> to the OS. </p>
<p >This is helpful to close, without invoking a native API (<code>close()</code> really), a value returned by <code>Peer_socket::release()</code> or, perhaps, received over a <code><a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a></code>.</p>
<p >The in-arg is nullified (it becomes <code>.null()</code>).</p>
<p >Nothing is logged; no errors are emitted. This is intended for no-questions-asked cleanup.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">peer_socket_native_or_null</td><td>The native socket to close. No-op (not an error) if it is <code>.null()</code>. If not <code>.null()</code>, <code>peer_socket_native_or_null.m_native_handle</code> must be suitable for <code>Peer_socket::native_handle()</code>. In practice the use case informing <a class="el" href="namespaceipc_1_1transport_1_1asio__local__stream__socket.html#af0833f160dffd7f1c6921d27883a186b" title="Little utility that returns the raw Native_handle suitable for Peer_socket to the OS.">release_native_peer_socket()</a> is: <code>peer_socket_native = p.release()</code>, where <code>p</code> is a <code>Peer_socket</code>. Update: Another use case came about: receiving <code>peer_socket_native</code> over a <code><a class="el" href="classipc_1_1transport_1_1Native__socket__stream.html" title="Implements both Native_handle_sender and Native_handle_receiver concepts by using a stream-oriented U...">Native_socket_stream</a></code>. </td></tr>
  </table>
  </dd>
</dl>

<p class="definition">Definition at line <a class="el" href="asio__local__stream__socket_8cpp_source.html#l00417">417</a> of file <a class="el" href="asio__local__stream__socket_8cpp_source.html">asio_local_stream_socket.cpp</a>.</p>

<p class="reference">Referenced by <a class="el" href="arena__lend_2src_2ipc_2session_2detail_2shm_2arena__lend_2jemalloc_2session__impl_8hpp_source.html#l00270">ipc::session::shm::arena_lend::jemalloc::Session_impl&lt; Session_impl_t &gt;::init_shm()</a>, and <a class="el" href="msg_8hpp_source.html#l01038">ipc::transport::struc::Msg_out&lt; Message_body, Struct_builder_t &gt;::store_native_handle_or_null()</a>.</p>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceipc_1_1transport_1_1asio__local__stream__socket_af0833f160dffd7f1c6921d27883a186b_icgraph.svg" width="596" height="131"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu May 2 2024 23:56:39 for Flow-IPC by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
